lib: Squash last use of GFile deltas_dir
authorColin Walters <walters@verbum.org>
Fri, 9 Dec 2016 04:05:39 +0000 (23:05 -0500)
committerAtomic Bot <atomic-devel@projectatomic.io>
Mon, 12 Dec 2016 15:50:11 +0000 (15:50 +0000)
I was having this thought today about making more of the OS readonly,
and ultimately if we got to the point where all ostree operations are
through the repo and sysroot dfds, we could have rpm-ostree be the
only process holding those fds open, and have a read-only bind mount
on top.

Anyways, we're not there, likely won't be soon, but this gets us
closer to being fully fd relative.

Closes: #628
Approved by: jlebon

src/libostree/ostree-repo-private.h
src/libostree/ostree-repo-static-delta-core.c
src/libostree/ostree-repo.c

index 6b25a6fc48da2eeb520d5783affe4b827814d77f..a4e59e44bce8836599f35dac65fe6ce99624b4a6 100644 (file)
@@ -72,7 +72,6 @@ struct OstreeRepo {
   int    cache_dir_fd;
   char  *cache_dir;
   int objects_dir_fd;
-  GFile *deltas_dir;
   int uncompressed_objects_dir_fd;
   GFile *sysroot_dir;
   char *remotes_config_dir;
index 5ef4df907814c06260e7c1884cc6261e4376394e..edbf965be86afb1be17e386410f49ed059798c26 100644 (file)
@@ -73,95 +73,100 @@ ostree_repo_list_static_delta_names (OstreeRepo                  *self,
                                      GCancellable                *cancellable,
                                      GError                     **error)
 {
-  gboolean ret = FALSE;
   g_autoptr(GPtrArray) ret_deltas = NULL;
-  g_autoptr(GFileEnumerator) dir_enum = NULL;
+  glnx_fd_close int dfd = -1;
 
   ret_deltas = g_ptr_array_new_with_free_func (g_free);
 
-  if (g_file_query_exists (self->deltas_dir, NULL))
+  dfd = glnx_opendirat_with_errno (self->repo_dir_fd, "deltas", TRUE);
+  if (dfd < 0)
     {
-      dir_enum = g_file_enumerate_children (self->deltas_dir, OSTREE_GIO_FAST_QUERYINFO,
-                                            G_FILE_QUERY_INFO_NOFOLLOW_SYMLINKS,
-                                            NULL, error);
-      if (!dir_enum)
-        goto out;
+      if (errno != ENOENT)
+        {
+          glnx_set_error_from_errno (error);
+          return FALSE;
+        }
+    }
+  else
+    {
+      g_auto(GLnxDirFdIterator) dfd_iter = { 0, };
+
+      if (!glnx_dirfd_iterator_init_take_fd (dfd, &dfd_iter, error))
+        return FALSE;
+      dfd = -1;
 
       while (TRUE)
         {
-          g_autoptr(GFileEnumerator) dir_enum2 = NULL;
-          GFileInfo *file_info;
-          GFile *child;
+          g_auto(GLnxDirFdIterator) sub_dfd_iter = { 0, };
+          struct dirent *dent;
 
-          if (!g_file_enumerator_iterate (dir_enum, &file_info, &child,
-                                          NULL, error))
-            goto out;
-          if (file_info == NULL)
+          if (!glnx_dirfd_iterator_next_dent_ensure_dtype (&dfd_iter, &dent, cancellable, error))
+            return FALSE;
+          if (dent == NULL)
             break;
-
-          if (g_file_info_get_file_type (file_info) != G_FILE_TYPE_DIRECTORY)
+          if (dent->d_type != DT_DIR)
             continue;
 
-
-          dir_enum2 = g_file_enumerate_children (child, OSTREE_GIO_FAST_QUERYINFO,
-                                                 G_FILE_QUERY_INFO_NOFOLLOW_SYMLINKS,
-                                                 NULL, error);
-          if (!dir_enum2)
-            goto out;
+          if (!glnx_dirfd_iterator_init_at (dfd_iter.fd, dent->d_name, FALSE,
+                                            &sub_dfd_iter, error))
+            return FALSE;
 
           while (TRUE)
             {
-              GFileInfo *file_info2;
-              GFile *child2;
+              struct dirent *sub_dent;
               const char *name1;
               const char *name2;
+              g_autofree char *superblock_subpath = NULL;
+              struct stat stbuf;
 
-              if (!g_file_enumerator_iterate (dir_enum2, &file_info2, &child2,
-                                              NULL, error))
-                goto out;
-              if (file_info2 == NULL)
+              if (!glnx_dirfd_iterator_next_dent_ensure_dtype (&sub_dfd_iter, &sub_dent,
+                                                               cancellable, error))
+                return FALSE;
+              if (sub_dent == NULL)
                 break;
-
-              if (g_file_info_get_file_type (file_info2) != G_FILE_TYPE_DIRECTORY)
+              if (dent->d_type != DT_DIR)
                 continue;
 
-              name1 = g_file_info_get_name (file_info);
-              name2 = g_file_info_get_name (file_info2);
-
-              {
-                g_autoptr(GFile) meta_path = g_file_get_child (child2, "superblock");
-
-                if (g_file_query_exists (meta_path, NULL))
-                  {
-                    g_autofree char *buf = g_strconcat (name1, name2, NULL);
-                    GString *out = g_string_new ("");
-                    char checksum[OSTREE_SHA256_STRING_LEN+1];
-                    guchar csum[OSTREE_SHA256_DIGEST_LEN];
-                    const char *dash = strchr (buf, '-');
-
-                    ostree_checksum_b64_inplace_to_bytes (buf, csum);
-                    ostree_checksum_inplace_from_bytes (csum, checksum);
-                    g_string_append (out, checksum);
-                    if (dash)
-                      {
-                        g_string_append_c (out, '-');
-                        ostree_checksum_b64_inplace_to_bytes (dash+1, csum);
-                        ostree_checksum_inplace_from_bytes (csum, checksum);
-                        g_string_append (out, checksum);
-                      }
-
-                    g_ptr_array_add (ret_deltas, g_string_free (out, FALSE));
-                  }
-              }
+              name1 = dent->d_name;
+              name2 = sub_dent->d_name;
+
+              superblock_subpath = g_strconcat (name2, "/superblock", NULL);
+              if (fstatat (sub_dfd_iter.fd, superblock_subpath, &stbuf, 0) < 0)
+                {
+                  if (errno != ENOENT)
+                    {
+                      glnx_set_error_from_errno (error);
+                      return FALSE;
+                    }
+                }
+              else
+                {
+                  g_autofree char *buf = g_strconcat (name1, name2, NULL);
+                  GString *out = g_string_new ("");
+                  char checksum[OSTREE_SHA256_STRING_LEN+1];
+                  guchar csum[OSTREE_SHA256_DIGEST_LEN];
+                  const char *dash = strchr (buf, '-');
+
+                  ostree_checksum_b64_inplace_to_bytes (buf, csum);
+                  ostree_checksum_inplace_from_bytes (csum, checksum);
+                  g_string_append (out, checksum);
+                  if (dash)
+                    {
+                      g_string_append_c (out, '-');
+                      ostree_checksum_b64_inplace_to_bytes (dash+1, csum);
+                      ostree_checksum_inplace_from_bytes (csum, checksum);
+                      g_string_append (out, checksum);
+                    }
+
+                  g_ptr_array_add (ret_deltas, g_string_free (out, FALSE));
+                }
             }
         }
     }
 
-  ret = TRUE;
   if (out_deltas)
     *out_deltas = g_steal_pointer (&ret_deltas);
- out:
-  return ret;
+  return TRUE;
 }
 
 gboolean
index b113ccc03c6505c8edd667909600815bdd345832..1c4ae6634eb7670adb5717cf790d6ecde52591ed 100644 (file)
@@ -521,7 +521,6 @@ ostree_repo_finalize (GObject *object)
     (void) close (self->cache_dir_fd);
   if (self->objects_dir_fd != -1)
     (void) close (self->objects_dir_fd);
-  g_clear_object (&self->deltas_dir);
   if (self->uncompressed_objects_dir_fd != -1)
     (void) close (self->uncompressed_objects_dir_fd);
   g_clear_object (&self->sysroot_dir);
@@ -606,8 +605,6 @@ ostree_repo_constructed (GObject *object)
 
   self->tmp_dir = g_file_resolve_relative_path (self->repodir, "tmp");
 
-  self->deltas_dir = g_file_get_child (self->repodir, "deltas");
-
   /* Ensure the "sysroot-path" property is set. */
   if (self->sysroot_dir == NULL)
     self->sysroot_dir = g_object_ref (_ostree_get_default_sysroot_path ());